package com.hsd.core.base.dao.impl;

import java.sql.SQLException;
import java.sql.Time;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.criterion.Example;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import com.hsd.core.base.dao.IBaseDAO;
import com.hsd.core.model.BaseBean;
import com.hsd.core.page.Finder;
import com.hsd.core.page.entity.Pagination;

@SuppressWarnings("unchecked")
public class BaseDAO extends HibernateDaoSupport implements IBaseDAO{
	@Autowired
	public void setSessionFactory0(SessionFactory sessionFactory) { 
	        super.setSessionFactory(sessionFactory);   
    }
	
	protected JdbcTemplate jdbcTemplate;
	@Autowired
	public void setJdbcTemplate(JdbcTemplate jdbcTemplate){
		this.jdbcTemplate = jdbcTemplate;
	}
	 
	public void save(Object obj){ 
		this.getHibernateTemplate().saveOrUpdate(obj);
	} 
	
	public void delete(Object obj){
		this.getHibernateTemplate().delete(obj);
	}
	
	public void update(Object obj){
		this.getHibernateTemplate().update(obj);
	}
	public Long getSeqNextVal(String seqName){
		Map dataMap = this.jdbcTemplate.queryForMap("select  nextval('"+seqName+"') as id from dual");
		Long id = new Long((Integer)dataMap.get("id"));
		return id;
	}
	
	/**
	 * 
	 * 功能:保存一个实例化对象
	 * 作者: hs
	 * 创建日期:2006-6-13
	 * @param baseBean
	 */
	public void saveObject(BaseBean baseBean) {
		getHibernateTemplate().saveOrUpdate(baseBean);
	}

	/**
	 * 
	 * 功能:更新一个实例化对象
	 * 作者: hs
	 * 创建日期:2006-6-13
	 * @param baseBean
	 */
	public void update(BaseBean baseBean) {
		getHibernateTemplate().update(baseBean);
	}
	
	/**
	 * 
	 * 功能:更新一个实例化对象
	 * 作者: hs
	 * 创建日期:2006-6-13
	 * @param baseBean
	 */
	public void save(BaseBean baseBean) {
		getHibernateTemplate().saveOrUpdate(baseBean);

	}

	/**
	 * 
	 * 功能:删除一个映射对象
	 * 作者: hs
	 * 创建日期:2006-6-13
	 * @param baseBean
	 */
	public void deleteObject(BaseBean baseBean) {
		getHibernateTemplate().delete(baseBean);
	}

	/**
	 * 
	 * 功能:删除一组映射对象
	 * 作者: hs
	 * 创建日期:2006-6-13
	 * @param list
	 */
	public void deleteList(Collection list) {
		getHibernateTemplate().deleteAll(list);
	}
	
	/**
	 * 
	 * 功能:保存一组映射对象
	 * 作者: hs
	 * 创建日期:2006-6-13
	 * @param list
	 */
	public void saveOrUpdateAll(Collection list) {
		getHibernateTemplate().saveOrUpdateAll(list);
	}
	
	/**
	 * 获取唯一对象
	 * @param c
	 * @param map
	 * @return
	 */
	public Object getUniqueObject(final Class c, final Map map) {   
		Object e = this.getHibernateTemplate().execute(new HibernateCallback() {   
            public Object doInHibernate(Session session)   
                    throws HibernateException, SQLException {   
                Criteria cri = session.createCriteria(c);   
                cri.add(Restrictions.allEq(map));   
                return cri.uniqueResult();   
            }   
        });   
        return e;
    }

	/**
	 * 
	 * 功能:根据类的对象class和id,返回id对应的对象实例
	 * 作者: hs
	 * 创建日期:2006-6-13
	 * @param entityClass   如:BugRecord.class
	 * @param id 主键
	 * @return
	 */
	public Object findByID(Class entityClass, Long id) {
		return getHibernateTemplate().get(entityClass, id);
	}
	
	/**
	 * 
	 * 功能:根据类的对象class和id,返回id对应的对象实例
	 * 作者: hs
	 * 创建日期:2006-6-13
	 * @param entityClass   如:BugRecord.class
	 * @param id 主键
	 * @return
	 */
	public Object findByID(Class entityClass, String id) {
		return getHibernateTemplate().get(entityClass, id);
	}
	
    /**
     * 功能:执行删除或更新类Hql语句，无返回值<br>
     * 作者: hs<br>
     * 创建日期:Jul 5, 2006
     * @param hql
     */
	@Override
    public void executeUpdate(final String hql){
        this.getHibernateTemplate().execute(new HibernateCallback(){
            public Object doInHibernate(Session sess){
                Query query=sess.createQuery(hql);
                query.executeUpdate();
                releaseSession(sess);
                return null;
               }
            }
        );
    }
    
    /**
     * 功能:执行带参数的删除或更新类的Hql语句，无返回值<br>
     * 参数的个数和顺序必须和hql语句中的问号相匹配<br>
     * 作者: hs<br>
     * 创建日期:Jul 5, 2006
     * @param hql
     * @param params
     */
    @Override
    public void executeUpdate(final String hql,final Object[] params){
        this.getHibernateTemplate().execute(new HibernateCallback(){
            public Object doInHibernate(Session sess){
                Query query=sess.createQuery(hql);
                if(null != params && params.length>0){
                    for(int i=0;i<params.length;i++){
                        Object obj=params[i];
                        if(obj instanceof Long){
                            query.setLong(i,((Long)obj).longValue());                            
                        }else if(obj instanceof String){
                            query.setString(i,obj.toString());
                        }else if(obj instanceof Double){
                            query.setDouble(i,((Double)obj).doubleValue());
                        }else if(obj instanceof Float){
                            query.setFloat(i,((Float)obj).floatValue());
                        }else if(obj instanceof Integer){
                            query.setInteger(i,((Integer)obj).intValue());
                        }else if(obj instanceof Date || obj instanceof Time){
                            query.setDate(i,(Date)obj);
                        }else if(obj instanceof Short){
                            query.setShort(i,((Short)obj).shortValue());
                        }else if(obj instanceof Boolean){
                            query.setBoolean(i,((Boolean)obj).booleanValue());
                        }
                    }
                }
                query.executeUpdate();
                releaseSession(sess);
                return null;
               }
            }
        );
    }
    
    /*
     *  （非 Javadoc）
     * @see cn.com.sgcc.core.base.IDao#delAllResultByProperty(java.lang.Class, java.lang.String, java.util.List)
     */
    public void delAllResultByProperty(Class clas,String propertyName,List valueList){
        if(null != clas){
            if(null != propertyName && !"".equals(propertyName)){
                if(null != valueList && valueList.size()>0){
                    StringBuffer hql=new StringBuffer("delete "+clas.getName()+" where "+propertyName+" in(");
                    for(int i=0; i<valueList.size();i++){
                        hql.append(valueList.get(i));
                        if(i!=valueList.size()-1){
                            hql.append(" ,");
                        }
                    }
                    hql.append(")");
                    this.executeUpdate(hql.toString());
                }
            }
        }
    }
    
    /*
     *  （非 Javadoc）
     * @see cn.com.sgcc.core.base.IDao#delAllResultByProperty(java.lang.Class, java.lang.String, java.lang.Object)
     */
    public void delAllResultByProperty(Class clas,String propertyName,Object value){
        if(null != clas){
            if(null != propertyName && !"".equals(propertyName)){
                if(null != value && !"".equals(value)){
                    String hql="delete "+clas.getName()+" where "+propertyName+" = ?";
                    this.executeUpdate(hql,new Object[]{value});
                }
            }
        }
        
    }
    
    
    /*
     * （非 Javadoc）
     * @see cn.com.sgcc.core.base.IDao#findByExampleUnique(java.lang.Class, java.lang.Object)
     */
    public Object findByExampleUnique(Class classObj,Object exampleObj){
        Criteria criteria = this.getSession().createCriteria(classObj)
        		.add(Example.create(exampleObj));
        return criteria.uniqueResult();
    }
    
    /*
     * （非 Javadoc）
     * @see cn.com.sgcc.core.base.IDao#findByExample(java.lang.Class, java.lang.Object)
     */
    public List findByExample(Class classObj,Object exampleObj){
        Criteria criteria = this.getSession().createCriteria(classObj)
        		.add(Example.create(exampleObj));
        return criteria.list();
    }
    
    /**
	 * 功能:公用的查找list的方法
	 * <br>作者: hs<br>
	 * 创建日期:2007-9-12
	 * @param hql
	 * @param param
	 * @return
	 */
	public List findList(String hql,Object param){
		if(null == param)
			return this.getHibernateTemplate().find(hql);
		else
			return this.getHibernateTemplate().find(hql,param);
	}
	
	/**
	 * 
	 * 功能: 获得列表 
	 * 创建日期:2006-12-14
	 * @param hql
	 * @return
	 */
	public List findList(String hql){
		return this.getHibernateTemplate().find(hql);
	}
	
	/**
	 * 根据条件查询列表
	 * @param c
	 * @param map
	 * @return
	 */
	public List findList(final Class c, final Map map) {   
        List list = this.getHibernateTemplate().executeFind(   
                new HibernateCallback() {   
                    public Object doInHibernate(Session session)   
                            throws HibernateException, SQLException {   
                        Criteria cri = session.createCriteria(c);   
                        cri.add(Restrictions.allEq(map));   
                        List e = cri.list();   
                        return e;   
                    }   
                });   
        return list;   
    }
	
	/**
	 * 根据条件查询列表并按指定字段排序
	 * @param c
	 * @param map
	 * @return
	 */
	public List findList(final Class c, final Map map,final String orderstr) {   
        List list = this.getHibernateTemplate().executeFind(   
                new HibernateCallback() {   
                    public Object doInHibernate(Session session)   
                            throws HibernateException, SQLException {   
                        Criteria cri = session.createCriteria(c);   
                        cri.add(Restrictions.allEq(map));   
                        if (orderstr != null) {   
                            cri.addOrder(Order.asc(orderstr));
                        }
                        List e = cri.list();   
                        return e;   
                    }   
                });   
        return list;   
    }

	public void saveObjectTans(BaseBean baseBean) {
		Session session = getHibernateTemplate().getSessionFactory().openSession();
		Transaction tc = session.beginTransaction();
		tc.begin();
		getHibernateTemplate().saveOrUpdate(baseBean);
		tc.commit();
		session.close();
	}
	
	
	/************************************分页使用SQL开始************************************************/
	/**
	 * 查询分页
	 * @param finder
	 * @param pageNo
	 * @param pageSize
	 * @return
	 */
	public Pagination find(Finder finder, int pageNo, int pageSize) {
		int totalCount = countQueryResult(finder);
		Pagination p = new Pagination(pageNo, pageSize, totalCount);
		if (totalCount < 1) {
			p.setList(new ArrayList());
			return p;
		}
		Query query = getSession().createQuery(finder.getOrigHql());
		finder.setParamsToQuery(query);
		query.setFirstResult(p.getFirstResult());
		query.setMaxResults(p.getPageSize());
		if (finder.isCacheable()) {
			query.setCacheable(true);
		}
		List list = query.list();
		p.setList(list);
		return p;
	}
	
	/**
	 * 获得Finder的记录总数
	 * 
	 * @param finder
	 * @return
	 */
	protected int countQueryResult(Finder finder) {
		Query query = getSession().createQuery(finder.getRowCountHql());
		finder.setParamsToQuery(query);
		if (finder.isCacheable()) {
			query.setCacheable(true);
		}
		return ((Number) query.iterate().next()).intValue();
	}
	/************************************分页使用SQL结束************************************************/
	/**
	 * 根据对应属性删除对应数据
	 * @param clazz
	 * @param params
	 * @param values
	 */
	public void deleteBeansByProperties(Class<?> clazz,String[] params,String[] values){
		if(null != clazz){
			if(null != params && null != values && params.length == values.length){
				StringBuilder hsql = new StringBuilder();
				hsql.append("delete " + clazz.getName() + " where 1 = 1 ");
				for(int index = 0;index < params.length;index++){
					hsql.append(" and " + params[index] + " = '" + values[index] + "'");
				}
				executeUpdate(hsql.toString());
			}
		}
	}
}
